﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

namespace Neto.Logging;

/// <summary>
///     提供日志记录功能的工具类
/// </summary>
public class LogX
{
    /// <summary>
    ///     存储日志对象的集合，键为文件夹名称，值为对应的日志工厂对象
    /// </summary>
    private static readonly ConcurrentDictionary<string, LogXFactory> Loggers = new();

    /// <summary>
    ///     获取或创建指定文件夹和类别的日志对象
    /// </summary>
    /// <param name="folderName">日志文件存储的文件夹名称，默认为 "all"</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    /// <returns>指定文件夹和类别的日志工厂对象</returns>
    public static LogXFactory GetLogger(string folderName = "all"
        , string categoryName = "default"
        , int maxRollingFiles = 24 * 30
        , long fileSizeLimitBytes = 100 * 1024 * 1024
        , bool useUtcTimestamp = false)
    {
        if (string.IsNullOrWhiteSpace(folderName)) folderName = "all";
        // 尝试从缓存中获取日志对象
        if (Loggers.TryGetValue(folderName, out var logXFactory)) return logXFactory;
        // 如果缓存中不存在，则创建新的日志对象
        logXFactory = new LogXFactory(folderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp);
        // 将新创建的日志对象添加到缓存中
        Loggers.TryAdd(folderName, logXFactory);

        // 返回日志对象
        return logXFactory;
    }


    /// <summary>
    ///     记录跟踪级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Trace(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Trace(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录跟踪级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Trace(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Trace(ex, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录信息级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Information(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Information(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录信息级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Information(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Information(ex, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录调试级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Debug(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Debug(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录调试级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Debug(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Debug(ex, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录警告级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Warning(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Warning(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录警告级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Warning(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Warning(ex, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录错误级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Error(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Error(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录错误级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Error(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Error(ex, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录致命错误级别的日志。
    /// </summary>
    /// <param name="content">日志内容。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Critical(string content,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Critical(content, logFolderName, isWebInfoLog);
    }

    /// <summary>
    ///     记录致命错误级别的日志。
    /// </summary>
    /// <param name="ex">异常对象。</param>
    /// <param name="logFolderName">日志文件夹名称。</param>
    /// <param name="isWebInfoLog">是否记录Web信息,默认true</param>
    /// <param name="categoryName">日志的类别名称，默认为 "default"</param>
    /// <param name="maxRollingFiles">滚动文件的最大数量，默认为 720（30 天）</param>
    /// <param name="fileSizeLimitBytes">单个日志文件的最大大小（字节），默认为 100MB</param>
    /// <param name="useUtcTimestamp">是否使用 UTC 时间戳，默认为 false</param>
    public static void Critical(Exception ex,
        string logFolderName = "",
        bool isWebInfoLog = false,
        string categoryName = "default",
        int maxRollingFiles = 24 * 30,
        long fileSizeLimitBytes = 100 * 1024 * 1024,
        bool useUtcTimestamp = false)
    {
        GetLogger(logFolderName, categoryName, maxRollingFiles, fileSizeLimitBytes, useUtcTimestamp)
            .Critical(ex, logFolderName, isWebInfoLog);
    }
}